又踩雷啦啊哈哈哈哈哈。
來重現一下遇到的情境吧
export class AppComponent implements OnInit {
  fruit : any = {
    apple: {},
    banana: {},
  };
  ngOnInit() {
    this.fruit = {
      apple: {
        id: 1,
        isSelect: false,
      },
      banana: {
        id: 2,
        isSelect: false,
      },
    };
  }
  onClick(isSelect: boolean) {
    this.fruit = {
      apple: {
        id: 1,
        isSelect,
      },
    };
  }
fruit 的物件,裡面有 apple 與 banana 這兩樣空物件OnInit 時,賦予了 apple 與 banana 值如圖,按下去後,噴錯了!

發現 banana 的 id 不見了,原來是我把 this.fruit 整個值給改掉了
本以為上述的寫法,只會修改我有填的值 XD
這裡我使用了 js 裡的解構賦值處理,也可以用來做 淺拷貝(shallow copy)
將 onClick 的寫測改成這樣
onClick(isSelect: boolean) {
  this.fruit = {
    ...this.fruit,  // shallow copy
    apple: {
      id: 1,
      isSelect,
    },
  };
}
來看看成果。嗯...沒噴錯了 XD 結案!

將原本的物件轉字串後再轉成物件,就會又是全新的一個物件了!
JSON.parse(JSON.stringify(objArray));
objArray 為要帶入的物件
本來以為是淺(深)拷貝的問題,後來仔細一看,原來是我自己搞錯了,將 this.fruit 裡面的整個值都蓋掉,所以才會噴錯,不過也剛好再度對深拷貝與淺拷貝的這件事加深印象。
案例:https://stackblitz.com/edit/angular-ivy-wvmptw
參考資料:
变量的解构赋值
深入探討 JavaScript 中的參數傳遞:call by value 還是 reference?
關於 JS 中的淺拷貝(shallow copy)以及深拷貝(deep copy)